Set up
suppressPackageStartupMessages({
library(tidyverse)
})
Read in data and process
tmb_vaf_df <- readr::read_tsv(tmb_vaf_file, guess_max = 100000, show_col_types = FALSE) %>%
filter(!tmb >= 10) %>%
select(Kids_First_Biospecimen_ID, Variant_Classification, gene_protein, mutation_count, region_size, tmb, VAF)
genomic_paired_df <- readr::read_tsv(genomic_paired_file, guess_max = 100000, show_col_types = FALSE) %>%
left_join(tmb_vaf_df, by = c("Kids_First_Biospecimen_ID")) %>%
filter(!is.na(tmb))
# Attention as some bs specimen might not have TMB!
# If that happens, we will end up with samples lacking timepoints.
# Which patient samples don't have TMB?
# genomic_paired_df %>%
# filter(is.na(tmb)) %>%
# unique() %>%
# regulartable() %>%
# fontsize(size = 12, part = "all")
descriptors_df <- genomic_paired_df %>%
group_by(Kids_First_Participant_ID) %>%
summarize(descriptors = paste(sort(tumor_descriptor), collapse = ", "),)
# Vector to order timepoints
timepoints <- c("Diagnosis", "Progressive", "Recurrence", "Deceased", "Second Malignancy", "Unavailable")
df <- genomic_paired_df %>%
left_join(descriptors_df, by = c("Kids_First_Participant_ID")) %>%
mutate(cgGFAC = case_when(grepl("High-grade glioma", cancer_group) ~ "HGG",
grepl("Diffuse midline glioma", cancer_group) ~ "DMG",
grepl("Atypical Teratoid Rhabdoid Tumor", cancer_group) ~ "ATRT",
grepl("Low-grade glioma", cancer_group) ~ "LGG",
TRUE ~ "Other"),
td_cgGFAC = case_when(grepl("Deceased", tumor_descriptor) ~ "xDeceased",
TRUE ~ tumor_descriptor),
log10_tmb = abs(log10(tmb)))
# Let's count #samples per cancer groups and timepoints.
# We will use the cg_id col that indicates cancer type as identified at the first diagnostic sample
timepoint_cg_n_df <- df %>%
count(cg_id, tumor_descriptor) %>%
dplyr::mutate(tumor_descriptor_cg_n = glue::glue("{cg_id}_{tumor_descriptor} (N={n})")) %>%
dplyr::rename(timepoint_cg_n = n)
# Let's count #samples per cancer groups and timepoints
timepoint_cgGFAC_n_df <- df %>%
count(cgGFAC, td_cgGFAC) %>%
dplyr::mutate(tumor_descriptor_cgGFAC_n = glue::glue("{cgGFAC}_{td_cgGFAC} (N={n})")) %>%
dplyr::rename(timepoint_cgGFAC_n = n)
# Create df to use for plots
df_plot <- df %>%
left_join(timepoint_cg_n_df, by = c("tumor_descriptor", "cg_id")) %>%
left_join(timepoint_cgGFAC_n_df, by = c("td_cgGFAC", "cgGFAC")) %>%
filter(!timepoint_cg_n <= 2,
!timepoint_cgGFAC_n <= 2,
!cg_id == "NA") %>%
mutate(tumor_descriptor = factor(tumor_descriptor),
tumor_descriptor = fct_relevel(tumor_descriptor, timepoints))
Warning: There was 1 warning in `mutate()`.
ℹ In argument: `tumor_descriptor = fct_relevel(tumor_descriptor, timepoints)`.
Caused by warning:
! 1 unknown level in `f`: Unavailable
# Read color palette
palette_df <- readr::read_tsv(palette_file, guess_max = 100000, show_col_types = FALSE)
# Define and order palette
palette <- palette_df$hex_codes
names(palette) <- palette_df$Variant_Classification
Warning: Unknown or uninitialised column: `Variant_Classification`.
# Define label for plots
Alteration_type <- df_plot$Variant_Classification
# Define ylim
ylim <- max(df_plot$log10_tmb)
What type of alterations we observe per tumor descriptor?
# Create bxp
print(ggpubr::ggboxplot(df_plot,
x = "tumor_descriptor",
y = "log10_tmb",
color = "Variant_Classification",
palette = palette) +
theme_Publication() +
scale_y_continuous(limits = c(0, ylim)) +
xlab("Timepoint") +
theme(axis.text.x = element_text(angle = 90)))

# Save the plot
ggsave(filename = "Alteration_type_timepoints.pdf",
path = plots_dir,
width = 15,
height = 8,
device = "pdf",
useDingbats = FALSE)
What type of alterations we observe per tumor descriptor in each
cancer group?
# Create bxp
print(ggpubr::ggboxplot(df_plot,
x = "tumor_descriptor",
y = "log10_tmb",
color = "Variant_Classification",
palette = palette) +
facet_wrap(~cg_id) +
theme_Publication() +
xlab("Timepoint") +
scale_y_continuous(limits = c(0, ylim)) +
theme(axis.text.x = element_text(angle = 90)))

# Save the plot
ggsave(filename = "Alteration_type_cancer_group.pdf",
path = plots_dir,
width = 25,
height = 18,
device = "pdf",
useDingbats = FALSE)
What type of alterations we observe per tumor descriptor in each
cancer group defined by cgGFAC?
df_plot_cgGFAC <- df_plot %>%
arrange(tumor_descriptor_cgGFAC_n)
#mutate(tumor_descriptor_cgGFAC_n = factor(tumor_descriptor_cgGFAC_n))
#df_plot_cgGFAC$tumor_descriptor_cgGFAC_n %>% levels()
# Create bxp
print(ggpubr::ggboxplot(df_plot_cgGFAC,
x = "tumor_descriptor_cgGFAC_n",
y = "log10_tmb",
color = "Variant_Classification",
palette = palette) +
theme_Publication() +
xlab("Timepoint") +
scale_y_continuous(limits = c(0, ylim)) +
theme(axis.text.x = element_text(angle = 90)))

# Save the plot
ggsave(filename = "Alteration_type_cgGFAC.pdf",
path = plots_dir,
width = 14,
height = 8,
device = "pdf",
useDingbats = FALSE)
cgGFAC_id <- as.character(unique(df_plot_cgGFAC$cgGFAC))
cgGFAC_id
[1] "ATRT" "DMG" "HGG" "LGG" "Other"
ATRT
DMG
HGG
LGG
Other
# Loop through variable
for (i in seq_along(cgGFAC_id)){
print(i)
df_sub <- df_plot_cgGFAC %>%
filter(cgGFAC == cgGFAC_id[i])
# Create bxp
print(ggpubr::ggboxplot(df_sub,
x = "tumor_descriptor_cgGFAC_n",
y = "log10_tmb",
color = "Variant_Classification",
palette = palette) +
theme_Publication() +
labs(title = paste(cgGFAC_id[i])) +
scale_y_continuous(limits = c(0, ylim)) +
theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust = 1)))
}
[1] 1

[1] 2

[1] 3

[1] 4

[1] 5

What type of alterations we observe per tumor descriptor in each
cancer group (add _n))?
cg <- as.character(unique(df_plot$cg_id))
cg
[1] "Embryonal tumor with multilayer rosettes"
[2] "Low-grade glioma"
[3] "Ependymoma"
[4] "Medulloblastoma"
[5] "Atypical Teratoid Rhabdoid Tumor"
[6] "Diffuse midline glioma"
[7] "High-grade glioma"
[8] "Ganglioglioma"
[9] "Meningioma"
[10] "Pilocytic astrocytoma"
[11] "CNS Embryonal tumor"
[12] "Neuroblastoma"
[13] "Schwannoma"
[14] "Chordoma"
[15] "Malignant peripheral nerve sheath tumor"
[16] "Choroid plexus carcinoma"
[17] "Adamantinomatous Craniopharyngioma"
[18] "Dysembryoplastic neuroepithelial tumor"
[19] "Ewing sarcoma"
[20] "Rosai-Dorfman disease"
[21] "Neurofibroma/Plexiform"
[22] "Glial-neuronal tumor"
[23] "Hemangioblastoma"
[24] "Craniopharyngioma"
Embryonal tumor with multilayer rosettes
Low-grade glioma
Ependymoma
Medulloblastoma
Atypical Teratoid Rhabdoid Tumor
Diffuse midline glioma
High-grade glioma
Ganglioglioma
Meningioma
Pilocytic astrocytoma
CNS Embryonal tumor
Neuroblastoma
Schwannoma
Chordoma
Malignant peripheral nerve sheath tumor
Choroid plexus carcinoma
Adamantinomatous Craniopharyngioma
Dysembryoplastic neuroepithelial tumor
Ewing sarcoma
Rosai-Dorfman disease
Neurofibroma/Plexiform
Glial-neuronal tumor
Hemangioblastoma
Craniopharyngioma
# Loop through variable
for (i in seq_along(cg)){
print(i)
df_sub <- df_plot %>%
filter(cg_id == cg[i])
# Create bxp
print(ggpubr::ggboxplot(df_sub,
x = "tumor_descriptor_cg_n",
y = "log10_tmb",
color = "Variant_Classification",
palette = palette) +
theme_Publication() +
xlab("Timepoint") +
labs(title = paste(cg[i])) +
scale_y_continuous(limits = c(0, ylim)) +
theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust = 1)))
}
[1] 1

[1] 2

[1] 3

[1] 4

[1] 5

[1] 6

[1] 7

[1] 8

[1] 9

[1] 10

[1] 11

[1] 12

[1] 13

[1] 14

[1] 15

[1] 16

[1] 17

[1] 18

[1] 19

[1] 20

[1] 21

[1] 22

[1] 23

[1] 24

What type of alterations we observe per tumor descriptor in each
cancer group and timepoint model?
tm <- as.character(unique(df_plot$timepoints_models))
tm
[1] "Dx-Rec" "Dx-Pro" "Dx-Dec" "Pro-Dec"
[5] "Rec-SM" "Pro-Rec" "Dx-SM" "Pro-Rec-Dec"
[9] "Dx-Pro-Rec" "Rec-Dec" "Dx-Pro-Rec-Dec" "Dx-Rec-Dec"
[13] "Dx-Pro-Dec"
Dx-Rec
Dx-Pro
Dx-Dec
Pro-Dec
Rec-SM
Pro-Rec
Dx-SM
Pro-Rec-Dec
Dx-Pro-Rec
Rec-Dec
Dx-Pro-Rec-Dec
Dx-Rec-Dec
Dx-Pro-Dec
# Loop through variable
for (i in seq_along(tm)){
print(i)
df_sub <- df_plot %>%
filter(timepoints_models == tm[i])
# Create bxp
print(ggpubr::ggboxplot(df_sub,
x = "tumor_descriptor",
y = "tmb",
color = "Variant_Classification",
palette = palette) +
facet_wrap(~cancer_group) +
theme_Publication() +
ylab("TMB") +
xlab("Timepoint") +
scale_y_continuous(limits = c(0, ylim)) +
theme(axis.text.x = element_text(angle = 90)))
}
[1] 1
Warning: Removed 224 rows containing non-finite values (`stat_boxplot()`).

[1] 2
Warning: Removed 1153 rows containing non-finite values (`stat_boxplot()`).

[1] 3
Warning: Removed 370 rows containing non-finite values (`stat_boxplot()`).

[1] 4
Warning: Removed 169 rows containing non-finite values (`stat_boxplot()`).

[1] 5
Warning: Removed 93 rows containing non-finite values (`stat_boxplot()`).

[1] 6
Warning: Removed 127 rows containing non-finite values (`stat_boxplot()`).

[1] 7

[1] 8
Warning: Removed 510 rows containing non-finite values (`stat_boxplot()`).

[1] 9
Warning: Removed 158 rows containing non-finite values (`stat_boxplot()`).

[1] 10

[1] 11
Warning: Removed 175 rows containing non-finite values (`stat_boxplot()`).

[1] 12

[1] 13
Warning: Removed 62 rows containing non-finite values (`stat_boxplot()`).

sessionInfo()
R version 4.2.3 (2023-03-15)
Platform: aarch64-apple-darwin20 (64-bit)
Running under: macOS Ventura 13.5.1
Matrix products: default
BLAS: /Library/Frameworks/R.framework/Versions/4.2-arm64/Resources/lib/libRblas.0.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/4.2-arm64/Resources/lib/libRlapack.dylib
locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
attached base packages:
[1] grid stats graphics grDevices utils datasets methods
[8] base
other attached packages:
[1] ggthemes_4.2.4 lubridate_1.9.2 forcats_1.0.0 stringr_1.5.0
[5] dplyr_1.1.2 purrr_1.0.1 readr_2.1.4 tidyr_1.3.0
[9] tibble_3.2.1 ggplot2_3.4.2 tidyverse_2.0.0
loaded via a namespace (and not attached):
[1] tidyselect_1.2.0 xfun_0.39 bslib_0.5.0 carData_3.0-5
[5] colorspace_2.1-0 vctrs_0.6.3 generics_0.1.3 htmltools_0.5.5
[9] yaml_2.3.7 utf8_1.2.3 rlang_1.1.1 jquerylib_0.1.4
[13] pillar_1.9.0 ggpubr_0.6.0 glue_1.6.2 withr_2.5.0
[17] bit64_4.0.5 lifecycle_1.0.3 munsell_0.5.0 ggsignif_0.6.4
[21] gtable_0.3.3 ragg_1.2.5 evaluate_0.21 labeling_0.4.2
[25] knitr_1.43 tzdb_0.4.0 fastmap_1.1.1 parallel_4.2.3
[29] fansi_1.0.4 highr_0.10 broom_1.0.5 scales_1.2.1
[33] backports_1.4.1 cachem_1.0.8 vroom_1.6.3 jsonlite_1.8.7
[37] abind_1.4-5 systemfonts_1.0.4 farver_2.1.1 bit_4.0.5
[41] textshaping_0.3.6 hms_1.1.3 digest_0.6.33 stringi_1.7.12
[45] rstatix_0.7.2 rprojroot_2.0.3 cli_3.6.1 tools_4.2.3
[49] magrittr_2.0.3 sass_0.4.7 crayon_1.5.2 car_3.1-2
[53] pkgconfig_2.0.3 timechange_0.2.0 rmarkdown_2.23 R6_2.5.1
[57] compiler_4.2.3
LS0tCnRpdGxlOiAiQ2xhc3NpZmljYXRpb24gb2YgVmFyaWFudHMgYWNyb3NzIHBhaXJlZCBsb25naXR1ZGluYWwgc2FtcGxlcyBpbiB0aGUgUEJUQSBDb2hvcnQiCmF1dGhvcjogJ0FudG9uaWEgQ2hyb25pIDxjaHJvbmlhQGNob3AuZWR1PiBhbmQgSm8gTHlubmUgUm9raXRhIDxyb2tpdGFAY2hvcC5lZHU+IGZvciBEM0InCmRhdGU6ICIyMDIzIgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazoKICAgIHRvYzogVFJVRQogICAgdG9jX2Zsb2F0OiBUUlVFCi0tLQoKIyBTZXQgdXAKYGBge3IgbG9hZC1saWJyYXJ5fQpzdXBwcmVzc1BhY2thZ2VTdGFydHVwTWVzc2FnZXMoewogIGxpYnJhcnkodGlkeXZlcnNlKQp9KQpgYGAKCiMjIERpcmVjdG9yaWVzIGFuZCBGaWxlIElucHV0cy9PdXRwdXRzCmBgYHtyIHNldC1kaXItYW5kLWZpbGUtbmFtZXN9CiMgRGV0ZWN0IHRoZSAiLmdpdCIgZm9sZGVyIC0tIHRoaXMgd2lsbCBiZSBpbiB0aGUgcHJvamVjdCByb290IGRpcmVjdG9yeQojIFVzZSB0aGlzIGFzIHRoZSByb290IGRpcmVjdG9yeSB0byBlbnN1cmUgcHJvcGVyIHNvdXJjaW5nIG9mIGZ1bmN0aW9ucyAKIyBubyBtYXR0ZXIgd2hlcmUgdGhpcyBpcyBjYWxsZWQgZnJvbQpyb290X2RpciA8LSBycHJvanJvb3Q6OmZpbmRfcm9vdChycHJvanJvb3Q6Omhhc19kaXIoIi5naXQiKSkKYW5hbHlzaXNfZGlyIDwtIGZpbGUucGF0aChyb290X2RpciwgImFuYWx5c2VzIiwgInRtYi12YWYtbG9uZ2l0dWRpbmFsIikKcmVzdWx0c19kaXIgPC0gZmlsZS5wYXRoKGFuYWx5c2lzX2RpciwgInJlc3VsdHMiKQppbnB1dF9kaXIgPC0gZmlsZS5wYXRoKGFuYWx5c2lzX2RpciwgImlucHV0IikKZmlsZXNfZGlyIDwtIGZpbGUucGF0aChyb290X2RpciwgImFuYWx5c2VzIiwgInNhbXBsZS1kaXN0cmlidXRpb24tYW5hbHlzaXMiLCAicmVzdWx0cyIpCgojIElucHV0IGZpbGVzCmdlbm9taWNfcGFpcmVkX2ZpbGUgPC0gZmlsZS5wYXRoKGZpbGVzX2RpciwgImdlbm9taWNfYXNzYXlzX21hdGNoZWRfdGltZV9wb2ludHNfZXh0ZW5kZWQudHN2IikgCnRtYl92YWZfZmlsZSA8LSBmaWxlLnBhdGgocmVzdWx0c19kaXIsICJ0bWJfdmFmX2dlbm9taWMudHN2IikKcGFsZXR0ZV9maWxlIDwtIGZpbGUucGF0aChyb290X2RpciwgImZpZ3VyZXMiLCAicGFsZXR0ZXMiLCAib25jb3ByaW50X2NvbG9yX3BhbGV0dGUudHN2IikKCiMgRmlsZSBwYXRoIHRvIHBsb3QgZGlyZWN0b3J5CnBsb3RzX2RpciA8LQogIGZpbGUucGF0aChhbmFseXNpc19kaXIsICJwbG90cyIpCmlmICghZGlyLmV4aXN0cyhwbG90c19kaXIpKSB7CiAgZGlyLmNyZWF0ZShwbG90c19kaXIpCn0KCnNvdXJjZShwYXN0ZTAocm9vdF9kaXIsICIvZmlndXJlcy9zY3JpcHRzL3RoZW1lLlIiKSkKYGBgCgojIyBSZWFkIGluIGRhdGEgYW5kIHByb2Nlc3MKYGBge3IgbG9hZC1wcm9jZXNzLWlucHV0c30KdG1iX3ZhZl9kZiA8LSByZWFkcjo6cmVhZF90c3YodG1iX3ZhZl9maWxlLCBndWVzc19tYXggPSAxMDAwMDAsIHNob3dfY29sX3R5cGVzID0gRkFMU0UpICU+JSAKICBmaWx0ZXIoIXRtYiA+PSAxMCkgJT4lIAogIHNlbGVjdChLaWRzX0ZpcnN0X0Jpb3NwZWNpbWVuX0lELCBWYXJpYW50X0NsYXNzaWZpY2F0aW9uLCBnZW5lX3Byb3RlaW4sIG11dGF0aW9uX2NvdW50LAlyZWdpb25fc2l6ZSwgdG1iLCBWQUYpCgpnZW5vbWljX3BhaXJlZF9kZiA8LSByZWFkcjo6cmVhZF90c3YoZ2Vub21pY19wYWlyZWRfZmlsZSwgZ3Vlc3NfbWF4ID0gMTAwMDAwLCBzaG93X2NvbF90eXBlcyA9IEZBTFNFKSAlPiUgCiAgbGVmdF9qb2luKHRtYl92YWZfZGYsIGJ5ID0gYygiS2lkc19GaXJzdF9CaW9zcGVjaW1lbl9JRCIpKSAlPiUKICBmaWx0ZXIoIWlzLm5hKHRtYikpIAoKCiMgQXR0ZW50aW9uIGFzIHNvbWUgYnMgc3BlY2ltZW4gbWlnaHQgbm90IGhhdmUgVE1CIQojIElmIHRoYXQgaGFwcGVucywgd2Ugd2lsbCBlbmQgdXAgd2l0aCBzYW1wbGVzIGxhY2tpbmcgdGltZXBvaW50cy4KCiMgV2hpY2ggcGF0aWVudCBzYW1wbGVzIGRvbid0IGhhdmUgVE1CPwojIGdlbm9taWNfcGFpcmVkX2RmICU+JSAKIyAgZmlsdGVyKGlzLm5hKHRtYikpICU+JSAKIyAgdW5pcXVlKCkgJT4lIAojICByZWd1bGFydGFibGUoKSAlPiUKIyAgZm9udHNpemUoc2l6ZSA9IDEyLCBwYXJ0ID0gImFsbCIpCgpkZXNjcmlwdG9yc19kZiA8LSBnZW5vbWljX3BhaXJlZF9kZiAlPiUKICBncm91cF9ieShLaWRzX0ZpcnN0X1BhcnRpY2lwYW50X0lEKSAlPiUKICBzdW1tYXJpemUoZGVzY3JpcHRvcnMgPSBwYXN0ZShzb3J0KHR1bW9yX2Rlc2NyaXB0b3IpLCBjb2xsYXBzZSA9ICIsICIpLCkgCgoKIyBWZWN0b3IgdG8gb3JkZXIgdGltZXBvaW50cwp0aW1lcG9pbnRzIDwtIGMoIkRpYWdub3NpcyIsICJQcm9ncmVzc2l2ZSIsICJSZWN1cnJlbmNlIiwgIkRlY2Vhc2VkIiwgIlNlY29uZCBNYWxpZ25hbmN5IiwgIlVuYXZhaWxhYmxlIikKCmRmIDwtIGdlbm9taWNfcGFpcmVkX2RmICU+JSAKICBsZWZ0X2pvaW4oZGVzY3JpcHRvcnNfZGYsIGJ5ID0gYygiS2lkc19GaXJzdF9QYXJ0aWNpcGFudF9JRCIpKSAlPiUgCiAgbXV0YXRlKGNnR0ZBQyA9IGNhc2Vfd2hlbihncmVwbCgiSGlnaC1ncmFkZSBnbGlvbWEiLCBjYW5jZXJfZ3JvdXApIH4gIkhHRyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBncmVwbCgiRGlmZnVzZSBtaWRsaW5lIGdsaW9tYSIsIGNhbmNlcl9ncm91cCkgfiAiRE1HIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyZXBsKCJBdHlwaWNhbCBUZXJhdG9pZCBSaGFiZG9pZCBUdW1vciIsIGNhbmNlcl9ncm91cCkgfiAiQVRSVCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBncmVwbCgiTG93LWdyYWRlIGdsaW9tYSIsIGNhbmNlcl9ncm91cCkgfiAiTEdHIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUgfiAiT3RoZXIiKSwKICAgICAgICAgdGRfY2dHRkFDID0gY2FzZV93aGVuKGdyZXBsKCJEZWNlYXNlZCIsIHR1bW9yX2Rlc2NyaXB0b3IpIH4gInhEZWNlYXNlZCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSB+IHR1bW9yX2Rlc2NyaXB0b3IpLAogICAgICAgICBsb2cxMF90bWIgPSBhYnMobG9nMTAodG1iKSkpCgojIExldCdzIGNvdW50ICNzYW1wbGVzIHBlciBjYW5jZXIgZ3JvdXBzIGFuZCB0aW1lcG9pbnRzLgojIFdlIHdpbGwgdXNlIHRoZSBjZ19pZCBjb2wgdGhhdCBpbmRpY2F0ZXMgY2FuY2VyIHR5cGUgYXMgaWRlbnRpZmllZCBhdCB0aGUgZmlyc3QgZGlhZ25vc3RpYyBzYW1wbGUKdGltZXBvaW50X2NnX25fZGYgPC0gZGYgJT4lIAogIGNvdW50KGNnX2lkLCB0dW1vcl9kZXNjcmlwdG9yKSAlPiUgCiAgZHBseXI6Om11dGF0ZSh0dW1vcl9kZXNjcmlwdG9yX2NnX24gPSBnbHVlOjpnbHVlKCJ7Y2dfaWR9X3t0dW1vcl9kZXNjcmlwdG9yfSAgKE49e259KSIpKSAlPiUgCiAgZHBseXI6OnJlbmFtZSh0aW1lcG9pbnRfY2dfbiA9IG4pIAoKIyBMZXQncyBjb3VudCAjc2FtcGxlcyBwZXIgY2FuY2VyIGdyb3VwcyBhbmQgdGltZXBvaW50cyAKdGltZXBvaW50X2NnR0ZBQ19uX2RmIDwtIGRmICU+JSAKICBjb3VudChjZ0dGQUMsIHRkX2NnR0ZBQykgJT4lIAogIGRwbHlyOjptdXRhdGUodHVtb3JfZGVzY3JpcHRvcl9jZ0dGQUNfbiA9IGdsdWU6OmdsdWUoIntjZ0dGQUN9X3t0ZF9jZ0dGQUN9ICAoTj17bn0pIikpICU+JSAKICBkcGx5cjo6cmVuYW1lKHRpbWVwb2ludF9jZ0dGQUNfbiA9IG4pIAoKIyBDcmVhdGUgZGYgdG8gdXNlIGZvciBwbG90cwpkZl9wbG90IDwtIGRmICU+JSAKICBsZWZ0X2pvaW4odGltZXBvaW50X2NnX25fZGYsIGJ5ID0gYygidHVtb3JfZGVzY3JpcHRvciIsICJjZ19pZCIpKSAlPiUKICBsZWZ0X2pvaW4odGltZXBvaW50X2NnR0ZBQ19uX2RmLCBieSA9IGMoInRkX2NnR0ZBQyIsICJjZ0dGQUMiKSkgJT4lIAogIGZpbHRlcighdGltZXBvaW50X2NnX24gPD0gMiwKICAgICAgICAgIXRpbWVwb2ludF9jZ0dGQUNfbiA8PSAyLAogICAgICAgICAhY2dfaWQgPT0gIk5BIikgJT4lIAogIG11dGF0ZSh0dW1vcl9kZXNjcmlwdG9yID0gZmFjdG9yKHR1bW9yX2Rlc2NyaXB0b3IpLAogICAgICAgICB0dW1vcl9kZXNjcmlwdG9yID0gZmN0X3JlbGV2ZWwodHVtb3JfZGVzY3JpcHRvciwgdGltZXBvaW50cykpCiAgICAgICAgCmBgYCAKCgpgYGB7ciBkZWZpbmUtcGFyYW1ldGVycy1mb3ItcGxvdHN9CiMgUmVhZCBjb2xvciBwYWxldHRlCnBhbGV0dGVfZGYgPC0gcmVhZHI6OnJlYWRfdHN2KHBhbGV0dGVfZmlsZSwgZ3Vlc3NfbWF4ID0gMTAwMDAwLCBzaG93X2NvbF90eXBlcyA9IEZBTFNFKSAKCiMgRGVmaW5lIGFuZCBvcmRlciBwYWxldHRlCnBhbGV0dGUgPC0gcGFsZXR0ZV9kZiRoZXhfY29kZXMKbmFtZXMocGFsZXR0ZSkgPC0gcGFsZXR0ZV9kZiRWYXJpYW50X0NsYXNzaWZpY2F0aW9uCgojIERlZmluZSBsYWJlbCBmb3IgcGxvdHMKQWx0ZXJhdGlvbl90eXBlIDwtIGRmX3Bsb3QkVmFyaWFudF9DbGFzc2lmaWNhdGlvbgoKIyBEZWZpbmUgeWxpbQp5bGltIDwtIG1heChkZl9wbG90JGxvZzEwX3RtYikKYGBgCgojIFdoYXQgdHlwZSBvZiBhbHRlcmF0aW9ucyB3ZSBvYnNlcnZlIHBlciB0dW1vciBkZXNjcmlwdG9yPwoKYGBge3IgcGxvdC10aW1lcG9pbnQsIGZpZy53aWR0aCA9IDE1LCBmaWcuaGVpZ2h0ID0gOCwgZmlnLmZ1bGx3aWR0aCA9IFRSVUV9CiMgQ3JlYXRlIGJ4cApwcmludChnZ3B1YnI6OmdnYm94cGxvdChkZl9wbG90LCAKICAgICAgICAgICAgICAgICAgICAgICAgeCA9ICJ0dW1vcl9kZXNjcmlwdG9yIiwgCiAgICAgICAgICAgICAgICAgICAgICAgIHkgPSAibG9nMTBfdG1iIiwgCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gIlZhcmlhbnRfQ2xhc3NpZmljYXRpb24iLAogICAgICAgICAgICAgICAgICAgICAgICBwYWxldHRlID0gcGFsZXR0ZSkgKwogICAgICAgIHRoZW1lX1B1YmxpY2F0aW9uKCkgKyAKICAgICAgICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygwLCB5bGltKSkgKwogICAgICAgIHhsYWIoIlRpbWVwb2ludCIpICsKICAgICAgICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkpCgojIFNhdmUgdGhlIHBsb3QKZ2dzYXZlKGZpbGVuYW1lID0gIkFsdGVyYXRpb25fdHlwZV90aW1lcG9pbnRzLnBkZiIsIAogICAgICAgcGF0aCA9IHBsb3RzX2RpciwgCiAgICAgICB3aWR0aCA9IDE1LCAKICAgICAgIGhlaWdodCA9IDgsIAogICAgICAgZGV2aWNlID0gInBkZiIsIAogICAgICAgdXNlRGluZ2JhdHMgPSBGQUxTRSkKYGBgCgoKIyBXaGF0IHR5cGUgb2YgYWx0ZXJhdGlvbnMgd2Ugb2JzZXJ2ZSBwZXIgdHVtb3IgZGVzY3JpcHRvciBpbiBlYWNoIGNhbmNlciBncm91cD8KCmBgYHtyIHBsb3QtY2ctaWQsIGZpZy53aWR0aCA9IDI1LCBmaWcuaGVpZ2h0ID0gMTgsIGZpZy5mdWxsd2lkdGggPSBUUlVFfQojIENyZWF0ZSBieHAKcHJpbnQoZ2dwdWJyOjpnZ2JveHBsb3QoZGZfcGxvdCwgCiAgICAgICAgICAgICAgICAgICAgICAgIHggPSAidHVtb3JfZGVzY3JpcHRvciIsIAogICAgICAgICAgICAgICAgICAgICAgICB5ID0gImxvZzEwX3RtYiIsIAogICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9ICJWYXJpYW50X0NsYXNzaWZpY2F0aW9uIiwKICAgICAgICAgICAgICAgICAgICAgICAgcGFsZXR0ZSA9IHBhbGV0dGUpICsKICAgICAgICBmYWNldF93cmFwKH5jZ19pZCkgKwogICAgICAgIHRoZW1lX1B1YmxpY2F0aW9uKCkgKyAKICAgICAgICB4bGFiKCJUaW1lcG9pbnQiKSArCiAgICAgICAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwgeWxpbSkpICsKICAgICAgICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkpCgojIFNhdmUgdGhlIHBsb3QKZ2dzYXZlKGZpbGVuYW1lID0gIkFsdGVyYXRpb25fdHlwZV9jYW5jZXJfZ3JvdXAucGRmIiwgCiAgICAgICBwYXRoID0gcGxvdHNfZGlyLCAKICAgICAgIHdpZHRoID0gMjUsIAogICAgICAgaGVpZ2h0ID0gMTgsIAogICAgICAgZGV2aWNlID0gInBkZiIsIAogICAgICAgdXNlRGluZ2JhdHMgPSBGQUxTRSkKYGBgCgoKIyBXaGF0IHR5cGUgb2YgYWx0ZXJhdGlvbnMgd2Ugb2JzZXJ2ZSBwZXIgdHVtb3IgZGVzY3JpcHRvciBpbiBlYWNoIGNhbmNlciBncm91cCBkZWZpbmVkIGJ5IGNnR0ZBQz8KCmBgYHtyIHBsb3QtY2dHRkFDLW4sIGZpZy53aWR0aCA9IDE0LCBmaWcuaGVpZ2h0ID0gOCwgZmlnLmZ1bGx3aWR0aCA9IFRSVUV9CmRmX3Bsb3RfY2dHRkFDIDwtIGRmX3Bsb3QgJT4lIAogIGFycmFuZ2UodHVtb3JfZGVzY3JpcHRvcl9jZ0dGQUNfbikKICAjbXV0YXRlKHR1bW9yX2Rlc2NyaXB0b3JfY2dHRkFDX24gPSBmYWN0b3IodHVtb3JfZGVzY3JpcHRvcl9jZ0dGQUNfbikpIAoKI2RmX3Bsb3RfY2dHRkFDJHR1bW9yX2Rlc2NyaXB0b3JfY2dHRkFDX24gJT4lIGxldmVscygpCgojIENyZWF0ZSBieHAKcHJpbnQoZ2dwdWJyOjpnZ2JveHBsb3QoZGZfcGxvdF9jZ0dGQUMsIAogICAgICAgICAgICAgICAgICAgICAgICB4ID0gInR1bW9yX2Rlc2NyaXB0b3JfY2dHRkFDX24iLCAKICAgICAgICAgICAgICAgICAgICAgICAgeSA9ICJsb2cxMF90bWIiLCAKICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSAiVmFyaWFudF9DbGFzc2lmaWNhdGlvbiIsCiAgICAgICAgICAgICAgICAgICAgICAgIHBhbGV0dGUgPSBwYWxldHRlKSArCiAgICAgICAgdGhlbWVfUHVibGljYXRpb24oKSArIAogICAgICAgIHhsYWIoIlRpbWVwb2ludCIpICsKICAgICAgICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygwLCB5bGltKSkgKwogICAgICAgIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKSkKCiMgU2F2ZSB0aGUgcGxvdApnZ3NhdmUoZmlsZW5hbWUgPSAiQWx0ZXJhdGlvbl90eXBlX2NnR0ZBQy5wZGYiLCAKICAgICAgIHBhdGggPSBwbG90c19kaXIsIAogICAgICAgd2lkdGggPSAxNCwgCiAgICAgICBoZWlnaHQgPSA4LCAKICAgICAgIGRldmljZSA9ICJwZGYiLCAKICAgICAgIHVzZURpbmdiYXRzID0gRkFMU0UpCgpgYGAKCgpgYGB7ciBwbG90LWNnR0ZBQy1uLWluZGl2aWR1YWwtcGxvdHMsIGZpZy53aWR0aCA9IDgsIGZpZy5oZWlnaHQgPSA2LCBmaWcuZnVsbHdpZHRoID0gVFJVRX0KY2dHRkFDX2lkIDwtIGFzLmNoYXJhY3Rlcih1bmlxdWUoZGZfcGxvdF9jZ0dGQUMkY2dHRkFDKSkKY2dHRkFDX2lkCgojIExvb3AgdGhyb3VnaCB2YXJpYWJsZQpmb3IgKGkgaW4gc2VxX2Fsb25nKGNnR0ZBQ19pZCkpewogIHByaW50KGkpCiAgZGZfc3ViIDwtIGRmX3Bsb3RfY2dHRkFDICU+JQogICAgICBmaWx0ZXIoY2dHRkFDID09IGNnR0ZBQ19pZFtpXSkKCiAgCiAgICMgQ3JlYXRlIGJ4cAogIHByaW50KGdncHVicjo6Z2dib3hwbG90KGRmX3N1YiwgCiAgICAgICAgICAgICAgICAgICAgICAgIHggPSAidHVtb3JfZGVzY3JpcHRvcl9jZ0dGQUNfbiIsIAogICAgICAgICAgICAgICAgICAgICAgICB5ID0gImxvZzEwX3RtYiIsIAogICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9ICJWYXJpYW50X0NsYXNzaWZpY2F0aW9uIiwKICAgICAgICAgICAgICAgICAgICAgICAgcGFsZXR0ZSA9IHBhbGV0dGUpICsKICAgICAgICB0aGVtZV9QdWJsaWNhdGlvbigpICsgCiAgICAgICAgbGFicyh0aXRsZSA9IHBhc3RlKGNnR0ZBQ19pZFtpXSkpICsKICAgICAgICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygwLCB5bGltKSkgKwogICAgICAgIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIHZqdXN0ID0gMC41LCBoanVzdCA9IDEpKSkKfQpgYGAKCiMgV2hhdCB0eXBlIG9mIGFsdGVyYXRpb25zIHdlIG9ic2VydmUgcGVyIHR1bW9yIGRlc2NyaXB0b3IgaW4gZWFjaCBjYW5jZXIgZ3JvdXAgKGFkZCBfbikpPwogCgpgYGB7ciBwbG90LW4sIGZpZy53aWR0aCA9IDEyLCBmaWcuaGVpZ2h0ID0gOCwgZmlnLmZ1bGx3aWR0aCA9IFRSVUV9CmNnIDwtIGFzLmNoYXJhY3Rlcih1bmlxdWUoZGZfcGxvdCRjZ19pZCkpCmNnCgojIExvb3AgdGhyb3VnaCB2YXJpYWJsZQpmb3IgKGkgaW4gc2VxX2Fsb25nKGNnKSl7CiAgcHJpbnQoaSkKICBkZl9zdWIgPC0gZGZfcGxvdCAlPiUKICAgICAgZmlsdGVyKGNnX2lkID09IGNnW2ldKQogIAogICMgQ3JlYXRlIGJ4cAogIHByaW50KGdncHVicjo6Z2dib3hwbG90KGRmX3N1YiwgCiAgICAgICAgICAgICAgICAgICAgICAgIHggPSAidHVtb3JfZGVzY3JpcHRvcl9jZ19uIiwgCiAgICAgICAgICAgICAgICAgICAgICAgIHkgPSAibG9nMTBfdG1iIiwgCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gIlZhcmlhbnRfQ2xhc3NpZmljYXRpb24iLAogICAgICAgICAgICAgICAgICAgICAgICBwYWxldHRlID0gcGFsZXR0ZSkgKwogICAgICAgIHRoZW1lX1B1YmxpY2F0aW9uKCkgKyAKICAgICAgICB4bGFiKCJUaW1lcG9pbnQiKSArCiAgICAgICAgbGFicyh0aXRsZSA9IHBhc3RlKGNnW2ldKSkgKwogICAgICAgIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKDAsIHlsaW0pKSArCiAgICAgICAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgdmp1c3QgPSAwLjUsIGhqdXN0ID0gMSkpKQp9CmBgYAoKCiMgV2hhdCB0eXBlIG9mIGFsdGVyYXRpb25zIHdlIG9ic2VydmUgcGVyIHR1bW9yIGRlc2NyaXB0b3IgaW4gZWFjaCBjYW5jZXIgZ3JvdXAgYW5kIHRpbWVwb2ludCBtb2RlbD8KCmBgYHtyIHBsb3QtdGltZXBvaW50LW1vZGVsLCBmaWcud2lkdGggPSAyNSwgZmlnLmhlaWdodCA9IDE4LCBmaWcuZnVsbHdpZHRoID0gVFJVRX0KdG0gPC0gYXMuY2hhcmFjdGVyKHVuaXF1ZShkZl9wbG90JHRpbWVwb2ludHNfbW9kZWxzKSkKdG0KCiMgTG9vcCB0aHJvdWdoIHZhcmlhYmxlCmZvciAoaSBpbiBzZXFfYWxvbmcodG0pKXsKICBwcmludChpKQogIGRmX3N1YiA8LSBkZl9wbG90ICU+JQogICAgICBmaWx0ZXIodGltZXBvaW50c19tb2RlbHMgPT0gdG1baV0pCiAgCiAgIyBDcmVhdGUgYnhwCiAgcHJpbnQoZ2dwdWJyOjpnZ2JveHBsb3QoZGZfc3ViLCAKICAgICAgICAgICAgICAgICAgICAgICAgeCA9ICJ0dW1vcl9kZXNjcmlwdG9yIiwgCiAgICAgICAgICAgICAgICAgICAgICAgIHkgPSAidG1iIiwgCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gIlZhcmlhbnRfQ2xhc3NpZmljYXRpb24iLAogICAgICAgICAgICAgICAgICAgICAgICBwYWxldHRlID0gcGFsZXR0ZSkgKwogICAgICAgIGZhY2V0X3dyYXAofmNhbmNlcl9ncm91cCkgKwogICAgICAgIHRoZW1lX1B1YmxpY2F0aW9uKCkgKwogICAgICAgIHlsYWIoIlRNQiIpICsKICAgICAgICB4bGFiKCJUaW1lcG9pbnQiKSArCiAgICAgICAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwgeWxpbSkpICsKICAgICAgICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkpCn0KYGBgCgoKYGBge3IgZWNobz1UUlVFfQpzZXNzaW9uSW5mbygpCmBgYAo=